package com.project.zsxd.server.sleepInfo.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.project.zsxd.server.clocksleep.service.IClockSleepService;
import com.project.zsxd.server.common.exception.SystemException;
import com.project.zsxd.server.common.util.LogUtil;
import com.project.zsxd.server.sleepInfo.entity.SleepInfo;
import com.project.zsxd.server.sleepInfo.mapper.SleepInfoMapper;
import com.project.zsxd.server.sleepInfo.service.ISleepInfoService;
import com.project.zsxd.server.user.entity.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.Date;
import java.util.Objects;

import static com.project.zsxd.server.common.enums.ResultEnum.FILL_CLOCK_OUT_LIMIT;
import static com.project.zsxd.server.common.util.LocalDateUtil.*;

/**
 * <p>
 * 早睡打卡统计信息 服务实现类
 * </p>
 *
 * @author kaler
 * @since 2023-02-18
 */
@Slf4j
@Service
public class SleepInfoServiceImpl extends ServiceImpl<SleepInfoMapper, SleepInfo> implements ISleepInfoService {

    @Autowired
    private IClockSleepService clockSleepService;

    @Override
    public void batchRefreshSleepInfo() {
        // 插入打卡用户
        LogUtil.info("start insertUserFromClock");
        baseMapper.insertUserFromClock();
        LogUtil.info("finish insertUserFromClock");
        // 统计累计打卡数
        LogUtil.info("start updateSleepTotal");
        baseMapper.updateSleepTotal();
        LogUtil.info("finish updateSleepTotal");
        // 统计当月累计打卡数
        LogUtil.info("start updateSleepMonth");
        String currentClockDate = clockSleepService.calSleepDate(new Date());
        LocalDate currentDate = parse(currentClockDate);
        String beginDate = format(getFirstOfMonth(currentDate));
        String endDate = format(getLastOfMonth(currentDate));
        baseMapper.updateSleepMonth(beginDate, endDate);
        LogUtil.info("finish updateSleepMonth");
        // 重置当月补卡数
        resetSleepFill();
        LogUtil.info("finish resetSleepFill");
    }

    @Override
    public SleepInfo querySleepInfo(User user) {
        return lambdaQuery()
                .eq(SleepInfo::getUserName, user.getUserName())
                .one();
    }

    @Override
    public void addOneClockSleep(User user, boolean isFill) {
        SleepInfo sleepInfo = querySleepInfo(user);
        // 首次打卡时，需要创建统计记录
        if (Objects.isNull(sleepInfo)) {
            sleepInfo = new SleepInfo();
            sleepInfo.setUserName(user.getUserName());
            sleepInfo.setSleepTotal(1);
            sleepInfo.setSleepMonth(1);
            sleepInfo.setSleepFill(isFill ? 1 : 0);
            sleepInfo.setCreatedBy(user.getUserName());
            sleepInfo.setUpdatedBy(user.getUserName());
            save(sleepInfo);
            return;
        }
        sleepInfo.setSleepTotal(sleepInfo.getSleepTotal() + 1);
        sleepInfo.setSleepMonth(sleepInfo.getSleepMonth() + 1);
        if (isFill) {
            // 补卡次数不能超过3次
            if (sleepInfo.getSleepFill() >= 3) {
                throw new SystemException(FILL_CLOCK_OUT_LIMIT);
            }
            sleepInfo.setSleepFill(sleepInfo.getSleepFill() + 1);
        }
        sleepInfo.setUpdatedBy(user.getUserName());
        sleepInfo.setUpdatedTime(new Date());
        updateById(sleepInfo);


    }

    private void resetSleepFill() {
        // 每月1号重置补卡次数
        int day = LocalDate.now().getDayOfMonth();
        if (day == 1) {
            lambdaUpdate().set(SleepInfo::getSleepFill, 0).update();
        }
    }
}
